package com.henu.acmrating.webmagic;

import com.henu.acmrating.utils.CommandUtil;
import org.jboss.logging.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author code4crafter@gmail.com <br>
 *         Date: 13-7-26 <br>
 *         Time: 下午1:41 <br>
 */
class WebDriverPool {
    private final Logger logger = Logger.getLogger(getClass());

    private final int capacity;

    private final static int STAT_RUNNING = 1;

    private final static int STAT_CLODED = 2;

    private final AtomicInteger stat = new AtomicInteger(STAT_RUNNING);

    /*
     * new fields for configuring phantomJS
     */
    private WebDriver mDriver = null;

    protected static DesiredCapabilities sCaps;

    /**
     * Configure the GhostDriver, and initialize a WebDriver instance. This part
     * of code comes from GhostDriver.
     * https://github.com/detro/ghostdriver/tree/master/test/java/src/test/java/ghostdriver
     *
     * @author bob.li.0718@gmail.com
     * @throws IOException io 异常
     */
    public void configure() throws IOException {

        // Prepare capabilities
        sCaps = new DesiredCapabilities();
        sCaps.setJavascriptEnabled(true);
        sCaps.setCapability("takesScreenshot", false);

        ChromeOptions options = new ChromeOptions();
        options.addArguments("--no-sandbox"); // 彻底停用沙箱
        options.addArguments("--hide-scrollbars"); // 隐藏滚动条, 应对一些特殊页面
        options.addArguments("--incognito"); // 隐身模式（无痕模式）
        options.addArguments("--headless"); //  浏览器不提供可视化页面
        options.addArguments("blink-settings=imagesEnabled=false"); // 不加载图片, 提升速度
        options.addArguments("--disable-infobars"); // 禁用浏览器正在被自动化程序控制的提示
        options.addArguments("--disable-extensions"); // 禁用拓展
        options.addArguments("--disable-gpu"); //  禁用GPU加速
        options.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
        options.addArguments("--disable-javascript"); // overcome limited resource problems
        mDriver = new ChromeDriver(options);
    }

    /**
     * store webDrivers created
     */
    private final List<WebDriver> webDriverList = Collections
            .synchronizedList(new ArrayList<>());

    /**
     * store webDrivers available
     */
    private final BlockingDeque<WebDriver> innerQueue = new LinkedBlockingDeque<>();

    public WebDriverPool(int capacity) {
        this.capacity = capacity;
    }


    public WebDriver get() throws InterruptedException {
        checkRunning();
        WebDriver poll = innerQueue.poll();
        if (poll != null) {
            return poll;
        }
        if (webDriverList.size() < capacity) {
            synchronized (webDriverList) {
                if (webDriverList.size() < capacity) {

                    // add new WebDriver instance into pool
                    try {
                        configure();
                        innerQueue.add(mDriver);
                        webDriverList.add(mDriver);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
        return innerQueue.take();
    }

    public void returnToPool(WebDriver webDriver) {
        checkRunning();
        innerQueue.add(webDriver);
    }

    protected void checkRunning() {
        if (!stat.compareAndSet(STAT_RUNNING, STAT_RUNNING)) {
            throw new IllegalStateException("Already closed!");
        }
    }

    public void closeAll() {
        boolean b = stat.compareAndSet(STAT_RUNNING, STAT_CLODED);
        if (!b) {
            throw new IllegalStateException("Already closed!");
        }
        for (WebDriver webDriver : webDriverList) {
            logger.info("Quit webDriver" + webDriver);
            webDriver.quit();
        }
//        quitChrome();
    }

    void quitChrome() {
        try {
            ArrayList<String> list = new ArrayList<>();
            list.add("/bin/sh");
            list.add("-c");
            list.add("kill -9 `ps -ef | grep chrome|awk '{print $2}' `");
            String result = CommandUtil.run(list.toArray(new String[list.size()]));
            logger.info("Quit webDriver:" + result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
